package com.yanyeori.webtest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageInfo;
import com.yanyeori.framework.core.interfaces.CacheMap;
import com.yanyeori.framework.core.model.WebResponse;
import com.yanyeori.framework.core.util.IdUtil;
import com.yanyeori.framework.core.util.JacksonUtil;
import com.yanyeori.framework.datasource.mybatisplus.service.impl.ServiceImpl;
import com.yanyeori.framework.datasource.util.PageUtil;
import com.yanyeori.framework.redis.cache.CacheHashMap;
import com.yanyeori.framework.redis.util.RedisUtil;
import com.yanyeori.framework.security.entity.User;
import com.yanyeori.webtest.bo.BankBO;
import com.yanyeori.webtest.entity.clear.BankEntity;
import com.yanyeori.webtest.mapper.BankMapper;
import com.yanyeori.webtest.service.BankService;
import com.yanyeori.webtest.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chenkuan
 * @since 2020/8/7
 */
@Slf4j
@Service
public class BankServiceImpl extends ServiceImpl<BankMapper, BankEntity> implements BankService {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public WebResponse<?> pageBank() {
        PageUtil.startPage();
        List<BankEntity> bankList = query().list();
        List<BankBO> bankBOList = PageUtil.convert(bankList, BankBO.class);
        log.info("bankList: {}", JacksonUtil.toJson(bankBOList));
//        testRedisCacheSet(bankBOList);
        return WebResponse.ok(new PageInfo<>(bankBOList)).message("分页查询Bank数据");
    }

    @Override
    public List<BankEntity> listBank() {
        return query().list();
    }

    @Override
    public WebResponse<BankEntity> getByBankId(String bankId) {
        LambdaQueryWrapper<BankEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BankEntity::getBankId, bankId);
        BankEntity bank = baseMapper.selectOne(queryWrapper);
        log.info("bank: {}", bank);
//        testRedisCacheGet();
        return WebResponse.ok(bank);
    }

    private static CacheMap<String, String> cacheMap = new CacheHashMap<>("cache-1");

    private void testRedisCacheSet(List<BankBO> bankBOList) {
        cacheMap.put("key1", "value1");
        cacheMap.put("key2", "value2");

        Map<String, String> map = new HashMap<>();
        map.put("key3", "value3");
        map.put("key4", "value4");
        cacheMap.putAll(map);

        cacheMap.put("key5", "value5", 10 * 1000);
        cacheMap.put("key6", "value6", 120 * 1000);

        redisUtil.set("key7", WebResponse.ok(bankBOList));

        redisUtil.set("key8", null);
    }

    private void testRedisCacheGet() {
        log.info("size: {}", cacheMap.size());
        log.info("value3: {}", cacheMap.get("key3"));
        log.info("value5: {}", cacheMap.get("key5"));
        log.info("value6: {}", cacheMap.get("key6"));
        log.info("values: {}", JacksonUtil.toJson(cacheMap.values()));
        WebResponse<List<BankBO>> response = redisUtil.get("key7");
        log.info("values: {}", JacksonUtil.toJson(response));
        log.info("values: {}", (Object) redisUtil.get("key8"));
    }

    @Override
    public WebResponse<?> saveBank(BankEntity bank) {
        bank.setUpdateTime(System.currentTimeMillis());
        bank.setUpdateUser("test1");
        baseMapper.insert(bank);
        return WebResponse.ok().message("插入Bank数据");
    }

    @Override
    public WebResponse<?> saveBankBatch(List<BankEntity> bankList) {
        saveBatch(bankList);
        return WebResponse.ok().message("插入Bank数据");
    }

    /**
     * 测试seata分布式事务
     *
     * @param isError 1-手动抛出报错
     */
//    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public WebResponse<?> updateBank(String isError) {
//        logger.info("当前XID={}", RootContext.getXID());
        String uuid = IdUtil.randomUUID().substring(0, 10);
        log.info("uuid={}", uuid);
        //bank
        BankEntity bank = new BankEntity();
        bank.setId(2L);
        bank.setUpdateUser(uuid);
        baseMapper.updateById(bank);
        //user
        User user = new User();
        user.setUsername("chen");
        user.setUpdateUser(uuid);
        userService.update(user);
        //异常
        if ("1".equals(isError)) {
            throw new RuntimeException("人为异常");
        }
        return WebResponse.ok().message("更新Bank数据");
    }
}
